using UnityEngine;
using UnityEngine.Pool;

namespace Utils
{
    /// <summary>
    /// 封装Unity ObjectPool
    /// </summary>
    public class ObjectPool<T> where T : MonoBehaviour
    {
        private readonly UnityEngine.Pool.ObjectPool<T> _pool;

        private readonly T _prefab;


        public ObjectPool(
            T prefab, 
            int defaultSize = 20,
            int maxSize = 100)
        {
            _prefab = prefab;
            
            const bool collectionCheck = true;
            _pool = new UnityEngine.Pool.ObjectPool<T>(
                CreatePooledObject,
                OnGetFromPool,
                OnReturnToPool,
                OnDestroyPooledObject,
                collectionCheck,
                defaultSize,
                maxSize
            );
        }

        public T Get()
        {
            return _pool.Get();
        }

        public void Release(T obj)
        {
            _pool.Release(obj);
        }
        
        private T CreatePooledObject()
        {
            T newObject = Object.Instantiate(_prefab);
            return newObject;
        }

        private void OnGetFromPool(T pooledObject)
        {
            pooledObject.gameObject.SetActive(true);
        }

        private void OnReturnToPool(T pooledObject)
        {
            pooledObject.gameObject.SetActive(false);
        }

        private void OnDestroyPooledObject(T bullet)
        {
            Object.Destroy(bullet.gameObject);
        }
    }
}
